package jp.ac.waseda.cs.washi.game.player;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import jp.ac.waseda.cs.washi.game.Settings;
import jp.ac.waseda.cs.washi.game.api.GameInfo;
import jp.ac.waseda.cs.washi.game.api.Player;
import jp.ac.waseda.cs.washi.game.api.PlayerAction;
import jp.ac.waseda.cs.washi.gameaiarena.runner.AbstractRunner;
import jp.ac.waseda.cs.washi.gameaiarena.runner.RunnerFactory;

public class GameRunnner extends AbstractRunner<GameInfo, PlayerAction, Player> {

	private final Player _player;
	private PlayerAction _nextAction;
	private GameInfo _info;

	public GameRunnner(Player player) {
		_player = player;
	}

	@Override
	public Player getPlyaer() {
		return _player;
	}

	@Override
	protected void runPreProcessing(GameInfo input) {
		_info = input;
		_nextAction = PlayerAction.NONE;
	}

	@Override
	protected void runProcessing() {
		_nextAction = _player.execute(_info);
	}

	@Override
	protected PlayerAction runPostProcessing() {
		return _nextAction;
	}

	public static AbstractRunner<GameInfo, PlayerAction, Player> create(
			Player player, boolean limittingTime, boolean ignoringException,
			ObjectInputStream ois, ObjectOutputStream oos) {
		AbstractRunner<GameInfo, PlayerAction, Player> runner;
		if (player == null) {
			player = new Player() {
				@Override
				public void initialize(GameInfo gameInfo) {
				}
				@Override
				public PlayerAction execute(GameInfo gameInfo) {
					return null;
				}
			};
		}
		runner = new GameRunnner(player);
		if (limittingTime) {
			runner = RunnerFactory.limittingTime(runner, Settings.MAX_AITIME);
		}
		if (ignoringException) {
			runner = RunnerFactory.ignoringException(runner);
		}
		if (ois != null) {
			runner = RunnerFactory.replayingStream(runner, ois);
		}
		if (oos != null) {
			runner = RunnerFactory.recordingStream(runner, oos);
		}
		return runner;
	}
}
